// ---------------------------------------------------------------------------------------------------------------------
//   Copyright (c) SRT Solutions 2009. All rights reserved.
// ---------------------------------------------------------------------------------------------------------------------

namespace SRTSolutions.Elevate.FuncExtensions
{
    using global::System;
    using global::System.Collections.Generic;

    /// <summary>
    /// Contains methods for memoizing functions.
    /// </summary>
    public static class MemoizeExtensions
    {
        /// <summary>
        /// Memoizes the specified function.
        /// </summary>
        /// <typeparam name="T">The type of the input argument.</typeparam>
        /// <typeparam name="TResult">The type of the result.</typeparam>
        /// <param name="func">The function to memoize.</param>
        /// <returns>a func that will execute the function, caching the result</returns>
        public static Func<T, TResult> Memoize<T, TResult>(this Func<T, TResult> func)
        {
            if (func == null)
                throw new ArgumentNullException("func", "func is null.");

            var table = new Dictionary<T, TResult>();

            return argument =>
            {
                if (table.ContainsKey(argument))
                {
                    return table[argument];
                }
                else
                {
                    var result = func(argument);
                    table.Add(argument, result);
                    return result;
                }
            };
        }
    }
}
